import { setLocal, getLocal } from "@util/index";
import { App } from "vue";

export interface Config<T> {
  target: "en" | "cn";
  en: T;
  cn: T;
}
export type getProps<Obj extends Record<any, any>> = {
  [Key in (keyof Obj) as Obj[Key] extends object ? `${string & Key}.${string & keyof Exclude<Obj[Key], keyof any>}` | Key : Key]: Key
}

export function getI18n<T extends Record<any, any>>(config: Config<T>) {
  return {
    install(app: App) {
      const i18n = reactive(config)

      // 初始化缓存
      const CACHE_KET = "__LANGUAGE__"
      const cached = getLocal(CACHE_KET)
      if (cached) i18n.target = cached
      else setLocal(CACHE_KET, i18n.target)

      // 添加全局属性
      app.config.globalProperties.$t = (prop: getProps<Config<T>["en"]>, ...regs: { en: string, cn: string }[]): string => {
        // 1 截取点
        const strArr = String(prop).split(".")
        // 2 判断对象 . 不能超过2
        let result = "";
        if (strArr.length > 2) {
          throw new Error("The maximum nestable object is 2")
        }
        // 恰巧等于2
        else if (strArr.length === 2) {
          const obj = i18n.target === "en" ? config.en[strArr[0]] : config.cn[strArr[0]]
          if (typeof obj === "object") {
            result = obj[strArr[1]]
          } else {
            throw new Error(`${prop} in the enverionment "${i18n.target}" not found`)
          }
        }
        else {
          // @ts-ignore
          result = i18n.target === "en" ? config.en[prop] : config.cn[prop]
        }
        // 替换数组存在
        if (regs[0]) {
          regs.forEach((v, i) => result = result.replace(`\$${i + 1}`, v[i18n.target]))
        }
        return result
      };

      // 修改语言
      app.provide("i18n", i18n)
    },
  };
}



